﻿using System;
using System.Web;
using System.Collections.Generic;
using WAD.WEB.AppCode;
using WAD.Model.JSON.Oauth;
using WAD.DAL;
using WAD.Model;
using WAD.Client2.WXPay;

namespace WAD.Client2.OAuth
{
    /// <summary>
    /// WXLogin2 的摘要说明
    /// </summary>
    public class WXLogin : AjaxBase
    {
        public override void AjaxMethodDispatch(String identity)
        {
            switch (identity)
            {
                case "login": this.Login(); break;
                case "callback_ios": this.CallBack_IOS(); break;
                case "callback": this.CallBack(); break;
            }
        }
        string code = ""; //微信返回的Code

        //页面初始化
        protected override void PageLoad()
        {
            base.PageLoad();
            code = Parse.String("code", "");
        }

        //发起微信登录请求
        [QD.Web.Ajax.AjaxMethod]
        public void Login()
        {
            //第一步： 获取code
            Response.Redirect(string.Format(WxPayConfig.AuthorizeUrl, WxPayConfig.APPID, HttpUtility.UrlEncode(WxPayConfig.AuthorizeBackUri)));
        }

        //微信授权后，回调(IOS使用)
        [QD.Web.Ajax.AjaxMethod]
        public void CallBack_IOS()
        {
            MWXLogin json = new MWXLogin();
            json.UnionID = Parse.String("unionid", "");
            json.HeadImgUrl = Parse.String("headimg", "");
            json.NickName = Parse.String("nickname", "");
            if (string.IsNullOrEmpty(json.NickName))
                json.NickName = Parse.String("username", "");

            MUser model = GetModel(json);
            //登录成功后的信息
            Dictionary<String, object> data = null;
            int code = DaoUser.Login(model, out data);
            switch (code)
            {
                case Message.Code.ERROR_NAME:
                    //SavaLog("2", string.Format("IOS 注册 name:{0} ## pwd:{1} ## login_type:{2} ## api_rs:{3} ## code:{4} ", model.name, model.pwd, model.login_type, model.api_rs, code));
                    Register(model);    //注册新账号
                    break;
                case Message.Code.ERROR_PWD:
                    JsonResult(Message.Code.ERROR_PWD, Message.Msg.ERROR_PWD);
                    break;
                case Message.Code.ERROR_STATE:
                    JsonResult(Message.Code.ERROR_STATE, Message.Msg.ERROR_STATE);
                    break;
                case Message.Code.SUCCESS:
                    JsonResult(Message.Code.SUCCESS, Message.Msg.SUCCESS, data);
                    break;
            }
            JsonResult(0, "登录异常");
        }


        //微信授权后，回调函数
        [QD.Web.Ajax.AjaxMethod]
        public void CallBack()
        {
            if (string.IsNullOrEmpty(code))
                JsonResult(500, "授权失败,code参数无效!");

            string openid = "";
            MUser model = Oauth(out openid);          //微信验证
            Log.Info(this.GetType().ToString(),model.wx_login_openid+"|"+model.wx_login_token);
            if (model != null)
                UserLogin(model, openid, model.api_rs);               //验证成功后，注册用户、登录
        }

        MUser Oauth(out string openid)
        {
            //第二步：根据code获取token
            var url2 =
                $"https://api.weixin.qq.com/sns/oauth2/access_token?appid={WxPayConfig.APPID}&secret={WxPayConfig.APPSECRET}&code={code}&grant_type=authorization_code";
            var html2 = GetHtml(url2);
            var json = JsonParse<MWXLogin>(html2);
            if (string.IsNullOrEmpty(json?.Access_Token))
                JsonResult(500, "'授权失败!无法获取access_token,返回值:' " + html2);
            var token = json?.Access_Token??"";
            Log.Info(this.GetType().ToString(), json?.Access_Token);
            //第三步： 根据openid和access_token查询用户信息
            var url3 =
                $"https://api.weixin.qq.com/sns/userinfo?access_token={json.Access_Token}&openid={json.OpenID}&lang=zh_CN";
            var html3 = GetHtml(url3);
            Log.Info(this.GetType().ToString(), html3);
            json = JsonParse<MWXLogin>(html3);

            //获取昵称、性别、头像、国家、省份、城市,openid等参数
            if (string.IsNullOrEmpty(json.OpenID))
                JsonResult(500, "授权失败!无法获取昵称、头像等信息,返回值:" + html3);

            openid = json.OpenID;
            var model= GetModel(json);
            model.wx_login_token = token;
            return model;
        }

        void UserLogin(MUser model, string openid, string unionid)
        {
            //登录成功后的信息
            Dictionary<String, object> data = null;
            int code = DaoUser.Login(model, out data);
            if (code == Message.Code.ERROR_NAME)
            {
                model.api_rs = openid;
                code = DaoUser.Login(model, out data);
                if (data != null && data["id"] != DBNull.Value)
                    EditUnionID(openid, unionid, data["id"]);   //将OpenID更新成UnionID
            }

            switch (code)
            {
                case Message.Code.ERROR_NAME:
                    //SavaLog("2", string.Format("异常注册 name:{0} ## pwd:{1} ## login_type:{2} ## api_rs:{3} ## code:{4} ## openid:{5}", model.name, model.pwd, model.login_type, model.api_rs, code, openid));
                    Register(model);    //注册新账号
                    break;
                case Message.Code.ERROR_PWD:
                    GoHome(Message.Code.ERROR_PWD, Message.Msg.ERROR_PWD, null);
                    break;
                case Message.Code.ERROR_STATE:
                    GoHome(Message.Code.ERROR_STATE, Message.Msg.ERROR_STATE, null);
                    break;
                case Message.Code.SUCCESS:
                    DaoUser.UpdateWxLoginInfo(model);
                    GoHome(code, "", data);
                    break;
            }
        }

        void Register(MUser model)
        {
            int code = DaoUser.Regist(model);
            if (code != Message.Code.SUCCESS)
                GoHome(500, "账号同步失败，请重试", null);

            Dictionary<String, object> data = null;
            code = DaoUser.Login(model, out data);

            if (code != Message.Code.SUCCESS)
                GoHome(500, "登录出现了问题，请重试", null);
            DaoUser.UpdateWxLoginInfo(model);
            GoHome(0, "", data);  //登录成功
        }

        MUser GetModel(MWXLogin json)
        {
            var rand = new Random();
            var model = new MUser
            {
                name = "wx" + rand.Next(10000000, 99999999),
                nick_name = json.NickName,
                logo = json.HeadImgUrl,
                login_type = 3,
                phone = "",
                pwd = "",
                qq = "",
                email = "",
                api_rs = json.UnionID,
                wx_login_openid = json.OpenID,
                wx_login_token = json.Access_Token
            };
            //头像,完整URL
            //1 账号密码登录，2 QQ登录，3微信登录
            //必须用unionID，这样才能保证app和网页登录是同一个微信账号
            if (Request.Cookies["a"] == null) return model;
            if (!string.IsNullOrEmpty(Request.Cookies["a"].Value))
                model.agentid = Convert.ToInt32(Request.Cookies["a"].Value);    //推荐人ID
            return model;
        }

        void GoHome(int code, string msg, Dictionary<string, object> data)
        {
            string param = string.Format("?action=oauth&code={0}&msg={1}", code, msg);
            if (data != null)
            {
                Dictionary<string, object>.Enumerator ie = data.GetEnumerator();
                while (ie.MoveNext())
                {
                    if (ie.Current.Key.Equals("id"))
                        param += "&user_id=" + ie.Current.Value;
                    if (ie.Current.Key.Equals("token"))
                        param += "&token=" + ie.Current.Value;
                    if (ie.Current.Key.Equals("parentid"))
                        param += "&parentid=" + ie.Current.Value;
                }
            }
            Response.Redirect(WJXConfig.Path.LoginUrl2 + param);
        }

        string GetHtml(String url)
        {
            return QD.Utils.WebHttpHelper.Request(url);
        }

        //旧版本的openid更新成UnionID(临时用的)
        void EditUnionID(string openid, string unionid, object user_id)
        {
            SavaLog("UnionID",
                $"更新UnionID update [user] set api_rs='{unionid}' where api_rs='{openid}' and id={user_id}");
            DAO.ExecuteNonQuery($"update [user] set api_rs='{unionid}' where api_rs='{openid}' and id={user_id}");
        }
    }
}